using BunnyEater.Common.ResponseOutput;
using BunnyEater.Domain.Base;
using BunnyEater.Domain.SystemManagement;
using BunnyEater.EntityFrameworkCore;
using BunnyEater.Repository.BaseRepository;
using BunnyEater.Repository.Extensions;
using BunnyEater.Service.SystemManagementService.RoleService.Dto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace BunnyEater.Service.SystemManagementService.RoleService
{
    /// <summary>
    /// 角色服务实现，提供角色的增删改查及分页等基础功能
    /// </summary>
    public class RoleService : IRoleService
    {
        private readonly BunnyEaterContext _bunnyEaterContext;
        private readonly IRepository<Role> _roleRepository;
        private readonly IRepository<RolePermissions> _rolePermissionsRepository;
        private readonly IRepository<Permissions> _permissionsRepository;
        private readonly ILogger<RoleService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public RoleService(BunnyEaterContext bunnyEaterContext, IRepository<Role> roleRepository, IRepository<RolePermissions> rolePermissionsRepository, IRepository<Permissions> permissionsRepository, ILogger<RoleService> logger)
        {
            _bunnyEaterContext = bunnyEaterContext;
            _roleRepository = roleRepository;
            _rolePermissionsRepository = rolePermissionsRepository;
            _permissionsRepository = permissionsRepository;
            _logger = logger;
        }

        /// <summary>
        /// 分页查询角色列表
        /// </summary>
        /// <param name="query">分页查询参数</param>
        /// <returns>分页角色列表</returns>
        public async Task<ResponseReturnsEntity<Page<RoleListDto>>> GetPagedRolesAsync(RolePagedQueryDto query)
        {
            try
            {
                var roles = _roleRepository.GetListQuery().Where(r => !r.IsDelete);

                if (!string.IsNullOrEmpty(query.SearchKeyword))
                {
                    roles = roles.Where(r =>
                        EF.Functions.Like(r.RoleNmae, $"%{query.SearchKeyword}%")
                    );
                }

                if (query.State.HasValue)
                {
                    roles = roles.Where(r => r.State == query.State.Value);
                }

                var result = await roles.ToPagedListAsync(
                    query.PageIndex,
                    query.PageSize,
                    null,
                    r => r.CreateTime,
                    false);

                // 获取所有角色的权限信息
                var roleIds = result.Items.Select(r => r.Id).ToList();
                var rolePermissions = _rolePermissionsRepository.GetListQuery()
                    .Where(rp => roleIds.Contains(rp.RoleId))
                    .ToList();

                var permissionIds = rolePermissions.Select(rp => rp.PermissionsId).Distinct().ToList();
                var permissions = _permissionsRepository.GetListQuery()
                    .Where(p => permissionIds.Contains(p.Id))
                    .ToList();

                var dtoPage = new Page<RoleListDto>
                {
                    Items = result.Items.Select(r =>
                    {
                        // 获取当前角色的权限ID列表
                        var currentRolePermissionIds = rolePermissions
                            .Where(rp => rp.RoleId == r.Id)
                            .Select(rp => rp.PermissionsId)
                            .ToList();

                        // 获取权限名称列表
                        var permissionNames = permissions
                            .Where(p => currentRolePermissionIds.Contains(p.Id))
                            .Select(p => p.PermissionsName)
                            .ToList();

                        return new RoleListDto
                        {
                            Id = r.Id,
                            RoleNmae = r.RoleNmae,
                            State = r.State,
                            PermissionNames = permissionNames.Any() ? string.Join("、", permissionNames) : null
                        };
                    }).ToList(),
                    PageNumber = result.PageNumber,
                    PageSize = result.PageSize,
                    TotalPages = result.TotalPages,
                    TotalItems = result.TotalItems
                };

                return ResponseReturnsEntity<Page<RoleListDto>>.Success(dtoPage);
            }
            catch (Exception ex)
            {
                _logger.LogError($"分页查询角色列表失败: {ex.Message}");
                return ResponseReturnsEntity<Page<RoleListDto>>.Fail($"查询失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 新增角色，并支持分配权限。操作包含事务，失败自动回滚。
        /// </summary>
        /// <param name="roleDto">角色信息及权限Id集合</param>
        /// <returns>操作结果，成功返回true，失败返回详细错误信息</returns>
        /// <remarks>
        /// 1. 支持同时为角色分配多个权限。
        /// 2. 角色和角色权限关联表(RolePermissions)的插入在同一事务中，任一失败均回滚。
        /// 3. 自动为主键Id赋值Guid字符串。
        /// 4. 捕获数据库异常和通用异常，记录详细日志。
        /// </remarks>
        public async Task<ResponseReturnsEntity<bool>> AddRole(RoleListDto roleDto)
        {
            using var transaction = await _bunnyEaterContext.Database.BeginTransactionAsync();
            try
            {
                var entity = new Role
                {
                    Id = Guid.NewGuid().ToString(),
                    RoleNmae = roleDto.RoleNmae,
                    State = roleDto.State,
                    CreateTime = DateTime.Now
                };
                var result = await _roleRepository.InsertEntityAsync(entity);

                // 角色权限关联
                if (roleDto.PermissionsIds != null && roleDto.PermissionsIds.Any())
                {
                    var rolePermissions = roleDto.PermissionsIds.Select(pid => new RolePermissions
                    {
                        Id = Guid.NewGuid().ToString(),
                        RoleId = entity.Id,
                        PermissionsId = pid
                    }).ToList();
                    await _rolePermissionsRepository.InsertEntityAsync(rolePermissions);
                }

                await transaction.CommitAsync();
                return ResponseReturnsEntity<bool>.Success(result > 0);
            }
            catch (DbUpdateException dbEx)
            {
                await transaction.RollbackAsync();
                _logger.LogError($"数据库更新异常，添加角色失败: {dbEx.Message}", dbEx);
                return ResponseReturnsEntity<bool>.Fail("数据库操作异常，添加角色失败，请检查数据有效性或联系管理员。");
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                _logger.LogError($"添加角色失败: {ex.Message}", ex);
                return ResponseReturnsEntity<bool>.Fail($"添加角色失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 修改角色
        /// </summary>
        public async Task<ResponseReturnsEntity<bool>> UptRole(RoleListDto roleDto)
        {
            var entity = await _roleRepository.GetEntityByIdAsync(new Role { Id = roleDto.Id });
            if (entity == null) return ResponseReturnsEntity<bool>.Fail("角色不存在");
            entity.RoleNmae = roleDto.RoleNmae;
            entity.State = roleDto.State;
            var result = await _roleRepository.UpdateEntityAsync(entity);
            return ResponseReturnsEntity<bool>.Success(result > 0);
        }

        /// <summary>
        /// 删除角色（软删除）
        /// </summary>
        public async Task<ResponseReturnsEntity<bool>> DeleteRole(string id)
        {
            var entity = await _roleRepository.GetEntityByIdAsync(new Role { Id = id });
            if (entity == null) return ResponseReturnsEntity<bool>.Fail("角色不存在");
            entity.IsDelete = true;
            var result = await _roleRepository.UpdateEntityAsync(entity);
            return ResponseReturnsEntity<bool>.Success(result > 0);
        }

        /// <summary>
        /// 修改角色状态
        /// </summary>
        public async Task<ResponseReturnsEntity<bool>> UpdateRoleState(string id, bool state)
        {
            var entity = await _roleRepository.GetEntityByIdAsync(new Role { Id = id });
            if (entity == null) return ResponseReturnsEntity<bool>.Fail("角色不存在");
            entity.State = state;
            var result = await _roleRepository.UpdateEntityAsync(entity);
            return ResponseReturnsEntity<bool>.Success(result > 0);
        }

        /// <summary>
        /// 根据ID获取角色
        /// </summary>
        public async Task<ResponseReturnsEntity<RoleListDto>> GetRoleById(string id)
        {
            var entity = await _roleRepository.GetEntityByIdAsync(new Role { Id = id });
            if (entity == null) return ResponseReturnsEntity<RoleListDto>.Fail("角色不存在");
            var dto = new RoleListDto
            {
                Id = entity.Id,
                RoleNmae = entity.RoleNmae,
                State = entity.State,
                PermissionNames = null
            };
            return ResponseReturnsEntity<RoleListDto>.Success(dto);
        }

        /// <summary>
        /// 获取角色详情（包含权限ID和名称）
        /// </summary>
        /// <param name="id">角色Id</param>
        /// <returns>角色详情</returns>
        public async Task<ResponseReturnsEntity<RoleDetailDto>> GetRoleDetailById(string id)
        {
            try
            {
                if (string.IsNullOrEmpty(id))
                {
                    return ResponseReturnsEntity<RoleDetailDto>.Fail("角色ID不能为空");
                }

                var role = await _roleRepository.GetEntityByIdAsync(new Role { Id = id });
                if (role == null)
                {
                    return ResponseReturnsEntity<RoleDetailDto>.Fail("角色不存在");
                }

                var rolePermissions = _rolePermissionsRepository.GetListQuery()
                    .Where(rp => rp.RoleId == id)
                    .ToList();
                var permissionIds = rolePermissions.Select(rp => rp.PermissionsId).ToList();
                var permissions = _permissionsRepository.GetListQuery()
                    .Where(p => permissionIds.Contains(p.Id))
                    .ToList();

                var permissionList = permissions.Select(p => new RolePermissionSimpleDto
                {
                    PermissionId = p.Id,
                    PermissionName = p.PermissionsName
                }).ToList();

                var roleDetail = new RoleDetailDto
                {
                    Id = role.Id,
                    RoleNmae = role.RoleNmae,
                    State = role.State,
                    Permissions = permissionList
                };

                return ResponseReturnsEntity<RoleDetailDto>.Success(roleDetail);
            }
            catch (Exception ex)
            {
                _logger.LogError($"获取角色详情失败: {ex.Message}");
                return ResponseReturnsEntity<RoleDetailDto>.Fail($"获取角色详情失败: {ex.Message}");
            }
        }
    }
}